
void function($) {
	

	var template = {
		'img-getter': "<div class='img-getter-content'><input type='file' class='img-getter' /></div>",
		'img-viwer': "<div class='img-viwer-content'><img class='img-viwer' src='#' alt='图片加载失败' /></div>",
		'controller': "<div class='controller'><button class='rotate-left'>向左转</button><button class='rotate-right'>向右转</button><button class='scale-up'>放大</button><button class='scale-down'>缩小</button><button class='cancel'>取消</button><button class='done'>生成头像</button></div>",
		'box': "<div class='box'></div>",
		'move-listener': "<div class='move-listener'></div>",
		'blur': '<div class="blur"><div class="top"></div><div class="bottom"></div><div class="left"></div><div class="right"></div></div>'
	}
	var defaultOption = {
		x: 0,
		y: 0,
		rotation: 0,
		time: 1,
		size: 100,
	}

	var rotationOrigin = [
		'50% 50%',
		'0 0',
		'50% 50%',
		'0 0'
	], tranlateDis = [
		'translate(0,0)',
		'translate(0,-100%)',
		'translate(0,0)',
		'translate(-100%,0)'
	]

	function picture_picker() {

	}

	picture_picker.prototype.init = function(dom, option) {
		var self = this;
		self.option = option || {};
		self.dom = dom;
		self.imgSize = {
			width: 0,
			height: 0
		}
		self.reset().render(dom).bindEvent(dom);
	}

	picture_picker.prototype.reset = function(opt) {
		var self = this;
		$.extend(self, defaultOption, opt || self.option);
		return self;
	}
	picture_picker.prototype.focusCenter = function() {
		var self = this, $dom = $(self.dom),
		size = {
			width: $dom.innerWidth(),
			height: $dom.innerHeight()
		};
		self.x = (size.width - self.imgSize.width * self.time) / 2;
		self.y = (size.height - self.imgSize.height * self.time) / 2;
		return self;
	}
	picture_picker.prototype.fitArea = function() {
		var self = this, $dom = $(self.dom),
		size = {
			width: $dom.innerWidth(),
			height: $dom.innerHeight()
		};
		self.scale(size.width / self.imgSize.width - self.time);
		return self;
	}

	picture_picker.prototype.render = function(dom) {
		var self = this, $dom = $(dom);
		for (var i in template) {
			if (!$dom.find('.' + i).length) {
				$dom.append($(template[i]));
			}
		}
		$dom.find('.box').width(self.size).height(self.size);

		var domSize = [$dom.width(), $dom.height()],
		    topSize = [domSize[0], (domSize[1] - self.size) / 2],
			bottomSize = [domSize[0], (domSize[1] - self.size) / 2],
			leftSize = [(domSize[0] - self.size) / 2, self.size],
			rightSize = [(domSize[0] - self.size) / 2, self.size];

		$dom
		.find('.blur .top').width(topSize[0]).height(topSize[1])
		.end().find('.blur .bottom').width(bottomSize[0]).height(bottomSize[1])
		.end().find('.blur .left').width(leftSize[0]).height(leftSize[1]).css('top', topSize[1])
		.end().find('.blur .right').width(rightSize[0]).height(rightSize[1]).css('top', topSize[1]);

		return self;
	}

	picture_picker.prototype.imgChange = function(url) {
		var self = this;
		
		$(self.dom)
		.find('.img-viwer')
		.attr('src', url)
		.one('load', function(e) {
			self.imgSize.width = this.naturalWidth;
			self.imgSize.height = this.naturalHeight;
			self
			.reset()
			.initImagePosition()
			.updateImagePosition()
			.show()
		})
		.one('error', function(e) {
			self.hide();
		})
		return self;
	}

	picture_picker.prototype.moveImg = function(dis) {
		var self = this;
		self.x += dis.x;
		self.y += dis.y;
		// self.updateImagePosition();
		return self;
	}

	picture_picker.prototype.initImagePosition = function() {
		var self = this;
		self
			.fitArea()
			.focusCenter();
		return self;
	}

	picture_picker.prototype.updateImagePosition = function() {
		var self = this, $dom = $(self.dom);
		$dom
		.find('.img-viwer-content').css({
			left: self.x + 'px',
			top: self.y + 'px',
			width: self.imgSize.width,
			height: self.imgSize.height,
			transform: ['scale(', self.time, ')'].join(''),
			transformOrigin: '0 0'
		})
		.find('.img-viwer').css({
			transform: ['rotate(', self.rotation * 90, 'deg)', tranlateDis[self.rotation]].join(''),
			transformOrigin: rotationOrigin[self.rotation]
		})
		return self;
	}

	picture_picker.prototype.rotate = function(v) {
		var self = this;
		// self.reset({
		// 	time: self.time,
		// 	rotation: (self.rotation + v + 4) % 4
		// });
		self.rotation = (self.rotation + v + 4) % 4

		var t = self.imgSize.width;
		self.imgSize.width = self.imgSize.height;
		self.imgSize.height = t;

		// self.focusCenter().updateImagePosition();
		return self;
	}

	picture_picker.prototype.rotateLeft = function() {
		var self = this;
		self.rotate(-1);
		return self;
	}

	picture_picker.prototype.rotateRight = function() {
		var self = this;
		self.rotate(1);
		return self;
	}

	picture_picker.prototype.scale = function(v) {
		var self = this, t = self.time + v;
		if (t * self.imgSize.width < 100 || t * self.imgSize.height < 100) {
			return;
		}
		self.time = t;
		// self.updateImagePosition();
		return self;
	}

	picture_picker.prototype.scaleUp = function() {
		var self = this;
		self.scale(0.173);
		return self;
	}

	picture_picker.prototype.scaleDown = function() {
		var self = this;
		self.scale(-0.173);
		return self;
	}

	picture_picker.prototype.show = function() {
		var self = this;
		$(self.dom).addClass('active');
		return self;
	}

	picture_picker.prototype.hide = function() {
		var self = this;
		$(self.dom).removeClass('active');
		return self;
	}

	picture_picker.prototype.getPicture = function() {
		var self = this;
		var $dom = $(self.dom);

		var t1 = $dom.offset(), t2 = $dom.find('.box').offset();

		var ofs = {
			top: t2.top - t1.top - self.y,
			left: t2.left - t1.left - self.x
		},  sp = [
			[ofs.left, ofs.top],
			[ofs.top, self.imgSize.width * self.time - ofs.left - self.size],
			[self.imgSize.width * self.time - ofs.left - self.size, self.imgSize.height * self.time - ofs.top - self.size],
			[self.imgSize.height * self.time - ofs.top - self.size, ofs.left]
		], rp = sp[self.rotation];

		var size = self.size / self.time;

		rp.left = rp[0] / self.time;
		rp.top = rp[1] / self.time;

		var temp = document.createElement('canvas');
		temp.width = size;
		temp.height = size;
		temp.getContext('2d').drawImage($dom.find('.img-viwer')[0], rp.left, rp.top, size, size, 0, 0, size, size);
		rotate(temp, 90 * self.rotation);

		var target  = scale({width:self.size, height:self.size}, temp, 'jpeg');
		
		return target;

	}

	picture_picker.prototype.bindEvent = function(dom) {
		var self = this, $dom = $(dom);
		if ($dom.data('binded')) {
			return;
		}
		var x, y, moving = false;
		$dom
		.data('binded', true)
		.on('selectstart', function(e) {
			console.log('please remove this output');
			e.preventDefault();
			return false;
		})
		.find('.move-listener').on({
			'mousedown': function(e) {
				x = e.clientX;
				y = e.clientY;
				moving = true;
			},
			'mousemove': function(e) {
				if (!moving || !$dom.is('.active')) {
					return;
				}
				self.moveImg({
					x: e.clientX - x,
					y: e.clientY - y
				}).updateImagePosition();
				x = e.clientX;
				y = e.clientY;
			},
			'mouseup mouseleave': function(e) {
				moving = false;
			}
		})
		.end()
		.find('.img-getter').on('change', function(e) {
			if (this.files[0] && /image\/\w+/.test(this.files[0].type)) {
				self.imgChange(getObjectURL(this.files[0]));
				this.value = '';
			} else {
				// not image get
				this.value = '';
			}
		})
		.end()
		.on('click', '.controller .rotate-left', function() {
			self.rotateLeft().focusCenter().updateImagePosition();
		})
		.on('click', '.controller .rotate-right', function() {
			self.rotateRight().focusCenter().updateImagePosition();
		})
		.on('click', '.controller .scale-up', function() {
			self.scaleUp().updateImagePosition();
		})
		.on('click', '.controller .scale-down', function() {
			self.scaleDown().updateImagePosition();
		})
		.on('click', '.controller .done', function() {
			$dom.trigger('imageCreate', [self.getPicture()]);
		})
		.on('click', '.controller .cancel', function() {
			self.hide();
		})
		return self;
	}

// util

function getObjectURL(file){   
    var url=null    
    if(window.createObjectURL!=undefined){ // basic
        url=window.createObjectURL(file)   
    }else if(window.URL!=undefined){ // mozilla(firefox)
        url=window.URL.createObjectURL(file)   
    } else if(window.webkitURL!=undefined){ // webkit or chrome
        url=window.webkitURL.createObjectURL(file)   
    }   
    return url   
}  


function rotate(canva, degrees) {
  var angle = degrees * Math.PI / 180;
  var ctx = canva.getContext("2d"), img = document.createElement('canvas');
  // var dataImg = ctx.getImageData(0, 0, canva.width, canva.height);
  var center = {
    x: canva.width / 2,
    y: canva.height / 2
  };

  copy(canva, img);

  ctx.clearRect(0, 0, canva.width, canva.height);
  ctx.translate(center.x, center.y);
  ctx.rotate(angle);
  ctx.translate(-center.x, -center.y);
  // ctx.fillRect(0, 0, canva.width, canva.height);
  ctx.drawImage(img, 0, 0, canva.width, canva.height);
  
  return canva;
}

function copy(canva, target) {
    var ctx = target.getContext("2d"),
    fromCtx = canva.getContext('2d');
    var dataImg = fromCtx.getImageData(0, 0, canva.width, canva.height);
    
    target.width = canva.width;
    target.height = canva.height;

    ctx.putImageData(dataImg, 0, 0);
    return target;
}



picture_picker.init = function(dom, option) {
	var obj = new picture_picker();
	obj.init(dom, option);
}

window.picture_picker = picture_picker;

$.fn.picture_picker = function(option) {
	return this.each(function() {
		picture_picker.init(this, option);
	});
}

}(jQuery);